/*
 * This source code is part of TWaver 4.0
 *
 * Serva Software PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 * Copyright 2002 - 2011 Serva Software. All rights reserved.
 */

package demo.network.miscellaneous.magnifier;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JComboBox;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import twaver.EnumType;
import twaver.EnumTypeManager;
import twaver.TUIManager;
import twaver.TWaverConst;
import twaver.TWaverUtil;
import twaver.network.NetworkToolBarFactory;
import twaver.network.TNetwork;
import twaver.network.background.ColorBackground;
import twaver.table.editor.TextureEditor;

public class MagnifierNetwork extends TNetwork{
	
	private Stroke stroke = new BasicStroke(4);
	private Color shadowColor =  new Color(0, 0, 0, 100); 
	private Color brimColor =new Color(255, 255, 255);
	
	private boolean enableMagnifier = false;
	private double magnifierZoom = 1.5;
	private double magnifierSize = 0.80;
	private int magnifierShape = TWaverConst.SHAPE_ROUND_RECTANGLE_HALF;
	private String textureType = TWaverConst.TEXTURE_GRID_DIAMOND;

	private Shape clipShape = null;
	
	static{
		TUIManager.registerAttachment(ServerAttachment.class.getName(),ServerAttachment.class);
		
		List list = new ArrayList();
		list.add(TWaverConst.TOOLBAR_SELECTION);
		list.add(TWaverConst.TOOLBAR_ZOOMIN);
		list.add(TWaverConst.TOOLBAR_ZOOMOUT);
		list.add(TWaverConst.TOOLBAR_ZOOMTOOVERVIEW);
		list.add(TWaverConst.TOOLBAR_ZOOMRESET);
		list.add(TWaverConst.TOOLBAR_FULLSCREEN);
		list.add("ServerStatusDemo_PanButton");
		
		NetworkToolBarFactory.registerButton("ServerStatusDemo_PanButton", MagnifierButton.class);
		NetworkToolBarFactory.registerToolbar("ServerStatusDemo_ToolBar", list);
	}
	
	public MagnifierNetwork(){
		this.setToolbarByName("ServerStatusDemo_ToolBar");
		this.setBackground(new ColorBackground(new Color(30, 63, 148)));
		
		final JComboBox shapeComboBox = TWaverUtil.createEnumComboBox(TWaverConst.ENUM_SHAPE, false, "left");
		EnumType type = EnumTypeManager.getInstance().getEnumType(TWaverConst.ENUM_SHAPE, new Integer(this.magnifierShape));
		shapeComboBox.setSelectedItem(type);
		shapeComboBox.setPreferredSize(new Dimension(shapeComboBox.getPreferredSize().width, 20));
		shapeComboBox.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				EnumType type = (EnumType)shapeComboBox.getSelectedItem();
				MagnifierNetwork.this.setMagnifierShape(((Integer)type.getValue()).intValue());
			}
		});
		
		final JComboBox textureComboBox = (JComboBox)(new TextureEditor()).getComponent();
		textureComboBox.setSelectedItem(this.textureType);
		textureComboBox.setPreferredSize(new Dimension(120, 20));
		textureComboBox.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				MagnifierNetwork.this.setTextureType((String)textureComboBox.getSelectedItem());
			}
		});		
		
		final JSlider sizeSlider = new JSlider(0*100, 1*100, (int)(magnifierSize*100));		
		sizeSlider.addChangeListener(new ChangeListener(){
			public void stateChanged(ChangeEvent e) {
				MagnifierNetwork.this.setMagnifierSize(sizeSlider.getValue()/100.0);
			}
		});
		
		final JSlider zoomSlider = new JSlider(1*10, 5*10, (int)(magnifierZoom*10));		
		zoomSlider.addChangeListener(new ChangeListener(){
			public void stateChanged(ChangeEvent e) {
				MagnifierNetwork.this.setMagnifierZoom(zoomSlider.getValue()/10.0);
			}
		});
				
		this.getToolbar().add(zoomSlider);
		this.getToolbar().add(sizeSlider);
		this.getToolbar().add(shapeComboBox);
		this.getToolbar().add(textureComboBox);
		this.getToolbarButtonByName("ServerStatusDemo_PanButton").doClick();

	}
	
	public boolean isEnableMagnifier(){
		return this.enableMagnifier;
	}
	
	public void enableMagnifier(boolean enableMagnifier){
		this.enableMagnifier = enableMagnifier;
		this.getCanvas().repaint();
	}
	
	public double getMagnifierZoom(){
		return this.magnifierZoom;
	}
	
	public void setMagnifierZoom(double magnifierZoom){
		if(magnifierZoom >= 1){
			this.magnifierZoom = magnifierZoom;
			this.getCanvas().repaint();	
		}		
	}
	
	public double getMagnifierSize() {
		return magnifierSize;
	}

	public void setMagnifierSize(double magnifierSize) {
		if(magnifierSize > 0 && magnifierSize <= 1){
			this.magnifierSize = magnifierSize;
			this.getCanvas().repaint();	
		}		
	}

	public int getMagnifierShape() {
		return magnifierShape;
	}

	public void setMagnifierShape(int magnifierShape) {
		this.magnifierShape = magnifierShape;
		this.getCanvas().repaint();	
	}
	
	public String getTextureType() {
		return textureType;
	}

	public void setTextureType(String textureType) {
		this.textureType = textureType;
		this.getCanvas().repaint();	
	}	
	
	public boolean isLegalPoint(Point point){
		if(point != null && this.clipShape != null){
			return this.clipShape.contains(point);
		}
		return false;
	}
	
	public void paintNetworkContent(Graphics g, double xScale, double yScale, boolean considerClipBounds) {
		super.paintNetworkContent(g, xScale, yScale, considerClipBounds);
		if(enableMagnifier){
			this.paintMagnifier((Graphics2D)g);
		}
	}
	
    private void paintMagnifier(Graphics2D g){
        Shape oldClip = g.getClip();
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        
        Rectangle rect = this.getCanvasScrollPane().getViewport().getViewRect();
        g.setColor(shadowColor);
        g.fill(rect);
        if(textureType != null){
	        Paint paint = TWaverUtil.createTexturePaint(textureType, Color.black);
	        g.setPaint(paint);
	        g.fill(rect);        	
        }
        
        double w = rect.width * (1-this.magnifierSize) / 2;
        double h = rect.height * (1-this.magnifierSize) / 2;
        rect.grow(-(int)w, -(int)h);  
        clipShape = TWaverUtil.createShape(magnifierShape, rect);
        
        rect = clipShape.getBounds();

        g.setColor(this.getCanvas().getBackground());
        g.fill(clipShape);
        g.setColor(brimColor);
        g.setStroke(stroke);
        g.draw(clipShape);
 
        double xTranslate = rect.getCenterX() * magnifierZoom - rect.getCenterX();
        double yTranslate = rect.getCenterY() * magnifierZoom - rect.getCenterY();

        g.clip(clipShape);
        g.translate(-xTranslate, -yTranslate);
        super.paintNetworkContent(g, this.getZoom() * magnifierZoom, this.getZoom() * magnifierZoom, false);
        g.translate(xTranslate, yTranslate);
       
        if (oldClip != null) {
            g.setClip(oldClip);
        }    	
    }
}